package org.lili.orika;

import ma.glasnost.orika.BoundMapperFacade;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.junit.BeforeClass;
import org.junit.Test;
import org.lili.model.source.*;
import org.lili.model.targets.Dest;
import org.lili.model.targets.PersonNameParts;
import org.lili.model.targets.Personne;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;

/**
 * @packgeName: org.lili.orika
 * @ClassName: Test1
 * @copyright: CopyLeft
 * @description:<描述>
 * @author: lili
 * @date: 2017/8/15-20:48
 * @version: 1.0
 * @since: JDK 1.8
 */
public class UnitTest {


    static MapperFactory mapperFactory;

    @BeforeClass
    public static void init() {
        mapperFactory = new DefaultMapperFactory.Builder().build();
    }

    @Test
    public void giveSrcAndDest_WhenMaps_thenCorrect(){

        mapperFactory.classMap(Source.class, Dest.class);
        MapperFacade mapper = mapperFactory.getMapperFacade();
        Source s = new Source("lili",10);
        Dest d = mapper.map(s,Dest.class);
        assertEquals(s.getAge(),d.getAge());
        assertEquals(s.getName(),d.getName());
//        assertEquals(s,d);
    }

    @Test
    public void givenSrcAndDest_whenMapsUsingBoundMapper_thenCorrect() {
        BoundMapperFacade<Source, Dest>
                boundMapper = mapperFactory.getMapperFacade(Source.class, Dest.class);
        Source src = new Source("baeldung", 10);
        Dest dest = boundMapper.map(src);

        assertEquals(dest.getAge(), src.getAge());
        assertEquals(dest.getName(), src.getName());
    }

    @Test
    public void givenSrcAndDest_whenMapsUsingBoundMapperInReverse_thenCorrect() {
        BoundMapperFacade<Source, Dest>
                boundMapper = mapperFactory.getMapperFacade(Source.class, Dest.class);
        Dest src = new Dest("baeldung", 10);
        Source dest = boundMapper.mapReverse(src);

        assertEquals(dest.getAge(), src.getAge());
        assertEquals(dest.getName(), src.getName());
    }

    @Test
    public void givenSrcAndDestWithDifferentFieldName_whenMaps_thenCorrect(){
        mapperFactory.classMap(Personne.class,Person.class)
                .field("nom", "name")
                .field("surnom", "nickname")
                .field("age", "age").register();
        MapperFacade mapper = mapperFactory.getMapperFacade();
        Personne frenchPerson = new Personne("Claire", "cla", 25);
        Person englishPerson = mapper.map(frenchPerson, Person.class);

        assertEquals(englishPerson.getName(), frenchPerson.getNom());
        assertEquals(englishPerson.getNickname(), frenchPerson.getSurnom());
        assertEquals(englishPerson.getAge(), frenchPerson.getAge());
    }


    @Test
    public void givenSrcAndDest_byDefault(){
        mapperFactory.classMap(Personne.class, Person.class)
                .field("nom", "name").field("surnom", "nickname").byDefault().register();
    }

    @Test
    public void givenSrcAndDest_whenCanExcludeField_thenCorrect() {

        mapperFactory.classMap(Personne.class, Person.class).exclude("nom")
                .field("surnom", "nickname").field("age", "age").register();
        MapperFacade mapper = mapperFactory.getMapperFacade();
        Personne frenchPerson = new Personne("Claire", "cla", 25);
        Person englishPerson = mapper.map(frenchPerson, Person.class);

//        assertEquals(null, englishPerson.getName());
        assertEquals(englishPerson.getNickname(), frenchPerson.getSurnom());
        assertEquals(englishPerson.getAge(), frenchPerson.getAge());
    }

    @Test
    public void givenSrcWithListAndDestWithPrimitiveAttributes_whenMaps_thenCorrect() {
        mapperFactory.classMap(PersonNameList.class, PersonNameParts.class)
                .field("nameList[0]", "firstName")
                .field("nameList[1]", "lastName").register();
        MapperFacade mapper = mapperFactory.getMapperFacade();
        List<String> nameList = Arrays.asList(new String[] { "Sylvester", "Stallone" });
        PersonNameList src = new PersonNameList(nameList);
        PersonNameParts dest = mapper.map(src, PersonNameParts.class);

        assertEquals(dest.getFirstName(), "Sylvester");
        assertEquals(dest.getLastName(), "Stallone");
    }

    @Test
    public void givenSrcWithMapAndDestWithPrimitiveAttributes_whenMaps_thenCorrect() {
        mapperFactory.classMap(PersonNameMap.class, PersonNameParts.class)
                .field("nameMap['first']", "firstName")
                .field("nameMap[\"last\"]", "lastName")
                .register();
        MapperFacade mapper = mapperFactory.getMapperFacade();
        Map<String, String> nameMap = new HashMap<>();
        nameMap.put("first", "Leornado");
        nameMap.put("last", "DiCaprio");
        PersonNameMap src = new PersonNameMap(nameMap);
        //Object -> Class
        PersonNameParts dest = mapper.map(src, PersonNameParts.class);

        assertEquals(dest.getFirstName(), "Leornado");
        assertEquals(dest.getLastName(), "DiCaprio");
    }

    @Test
    public void givenSrcWithNestedFields_whenMaps_thenCorrect() {
        mapperFactory.classMap(PersonContainer.class, PersonNameParts.class)
                .field("name.firstName", "firstName")
                .field("name.lastName", "lastName").register();
        MapperFacade mapper = mapperFactory.getMapperFacade();
        PersonContainer src = new PersonContainer(new Name("Nick", "Canon"));
        PersonNameParts dest = mapper.map(src, PersonNameParts.class);

        assertEquals(dest.getFirstName(), "Nick");
        assertEquals(dest.getLastName(), "Canon");
    }


    @Test
    public void givenSrcWithNullField_whenMapsThenCorrect() {
        mapperFactory.classMap(Source.class, Dest.class).byDefault();
        MapperFacade mapper = mapperFactory.getMapperFacade();
        Source src = new Source(null, 10);
        Dest dest = mapper.map(src, Dest.class);
        assertEquals(dest.getAge(), src.getAge());
        assertEquals(dest.getName(), src.getName());
    }













}
